<template>
  <view>
    <view class="video-container">
      <view class="video-view">
        <uni-row :gutter="10" style="width: 100%" class="row-content">
          <uni-col :span="8" v-for="(item, index) in formatVideos" :key="index">
            <div class="grid-content">
              <video
                :id="'video' + item.id"
                class="item-video"
                :ref="'video' + item.id"
                :src="this.baseURL + '/static/video/' + item.src"
                :controls="false"
                objectFit="cover"
                show-mute-btn="true"
                :muted="videoMuted"
                :poster="this.baseURL + item.poster"
                show-center-play-btn="false"
                @play="onPlay(item.id)"
                @error="onError"
                @loadedmetadata="onLoaded"
              ></video>
              <view class="video-desc">{{ item.desc }}</view>
              <!-- <span style="color: red; font-size: 14px">{{
                item.playIconClass
              }}</span> -->
              <view class="like-box">
                <view
                  class="like-icon-box"
                  @click="handlePlay(item.id, this.videoType)"
                >
                  <view v-if="videoType === 'video' || videoType === 'dynamic'">
                    <i
                      :id="'icon-like' + item.id"
                      :class="item.playIconClass"
                      :style="{
                        color: item.iconColor || '#fff',
                        fontSize: '26px',
                      }"
                    ></i>
                  </view>
                  <view v-else>
                    <i
                      :id="'icon-like' + item.id"
                      class="iconfont icon-like"
                      style="font-size: 26px"
                      :style="{ color: item.likeColor || '#ccc' }"
                    ></i>
                  </view>
                </view>
                <text class="like-count">{{ item.likeCount }}</text>
                <view class="like-item" @click="toggleVolume(item)">
                  <i
                    :id="'icon-volume' + item.id"
                    class="iconfont"
                    :class="
                      this.hasVolume ? 'icon-volume-on' : 'icon-volume-off'
                    "
                    style="font-size: 24px; color: #ccc"
                  ></i>
                </view>
              </view>
            </div>
          </uni-col>
        </uni-row>
        <uni-row :gutter="10" class="row-end" :center="true">
          <uni-col :span="24" class="col-end"
            ><text style="text-align: center"> 暂时没有更多了</text>
          </uni-col>
        </uni-row>
      </view>
    </view>
  </view>
</template>

<script>
  export default {
    name: "MeVideo",
    props: {
      videoList: {
        type: Array,
        default: () => [],
      },
      videoType: {
        type: String,
        default: "video",
      },
    },
    components: {},
    data() {
      return {
        videoElList: [],
        videoPlayEl: null,
        videoMuted: true,
        currentPlayId: null,
        // 新增：记录当前播放的视频上下文
        currentVideoContext: null,
        hasVolume: false,
        isLoaded: false,
        // 新增：缓存所有视频的上下文（避免重复创建）
        videoContextCache: {},
        formatVideos: [],
        mouseenterListeners: new WeakMap(),
        mouseleaveListeners: new WeakMap(),
      };
    },
    computed: {},
    methods: {
      onLoaded() {
        this.isLoaded = true;
      },
      onPlay(id) {
        // 1. 基础校验：视频未加载完成则不处理
        if (!this.isLoaded) return;

        // 2. 处理“互斥播放”：暂停之前正在播放的视频
        this.pausePrevVideo(id);

        // 3. 创建并缓存当前视频的上下文（避免重复创建）
        this.createCurrentVideoContext(id);

        // 4. 切换当前视频的图标：icon-play → icon-pause
        this.updatePlayIcon(id, true); // true 表示“正在播放”

        // 5. 处理音量状态（按当前视频单独控制，避免全局污染）
        // this.handleVolumeWhenPlay(id);

        // 6. 记录当前播放状态（更新 currentPlayId 和 currentVideoContext）
        this.currentPlayId = id;
        this.currentVideoContext = this.videoContextCache[id];
      },
      // 【新增辅助方法】创建并缓存当前视频的上下文
      createCurrentVideoContext(id) {
        const videoId = `video${id}`;
        // 若已缓存上下文，直接复用；否则创建新的
        if (!this.videoContextCache[id]) {
          this.videoContextCache[id] = uni.createVideoContext(videoId, this);
          // 校验上下文是否有效（容错）
          if (!this.videoContextCache[id]) {
            console.error(`视频上下文创建失败，videoId: ${videoId}`);
          }
        }
      },
      updateLikeColor(id) {
        const videoIndex = this.formatVideos.findIndex(
          (item) => item.id === id
        );
        let likeColor = this.formatVideos[videoIndex].likeColor;
        if (likeColor === "#f00") {
          likeColor = "#ccc";
          this.formatVideos[videoIndex].likeCount--;
        } else {
          likeColor = "#f00";
          this.formatVideos[videoIndex].likeCount++;
        }
        this.formatVideos[videoIndex].likeColor = likeColor;
        this.$set(this.formatVideos, videoIndex, {
          ...this.formatVideos[videoIndex],
        });
      },

      // 【新增辅助方法】更新播放/暂停图标（精准到单个视频）
      // isPlaying: true 表示“正在播放”，false 表示“已暂停”
      updatePlayIcon(id, isPlaying) {
        // 1. 找到当前视频在列表中的索引
        const videoIndex = this.formatVideos.findIndex(
          (item) => item.id === id
        );
        if (videoIndex === -1) {
          console.warn(`未找到 ID 为 ${id} 的视频`);
          return;
        }

        // 2. 拼接新的类名和颜色
        const newClass = isPlaying
          ? "iconfont icon-pause" // 播放中 → 显示 pause
          : "iconfont icon-play"; // 暂停 → 显示 play
        const newColor = isPlaying ? "#fff" : "#fff"; // 播放中改颜色
        // 3. Vue 中更新数组元素的正确方式
        this.formatVideos[videoIndex].playIconClass = newClass;
        this.formatVideos[videoIndex].iconColor = newColor;

        // 触发视图更新（Vue 2 中直接修改数组元素需要用 $set 或重新赋值数组）
        this.$set(this.formatVideos, videoIndex, {
          ...this.formatVideos[videoIndex],
        });
      },

      // 【新增辅助方法】播放时处理音量状态（跨平台兼容）
      handleVolumeWhenPlay(id) {},
      pausePrevVideo(id) {
        if (
          this.currentPlayId &&
          this.currentPlayId !== id &&
          this.currentVideoContext
        ) {
          // 暂停之前的视频
          this.currentVideoContext.pause();
          // 切换之前视频的图标：icon-pause → icon-play
          this.updatePlayIcon(this.currentPlayId, false); // false 表示“已暂停”
          // 清空之前的播放状态
          this.currentPlayId = null;
          this.currentVideoContext = null;
        }
      },
      onError(e) {
        console.error("视频错误信息：", e);
      },
      handlePlay(id, videoType) {
        if (videoType === "like") {
          this.updateLikeColor(id);
          return;
        }
        // 1. 先创建/获取当前视频上下文
        this.createCurrentVideoContext(id);
        const currentContext = this.videoContextCache[id];
        if (!currentContext || !this.isLoaded) return;

        // 2. 判断当前视频是否正在播放
        const isCurrentPlaying = this.currentPlayId === id;

        if (isCurrentPlaying) {
          // 情况1：当前视频正在播放 → 暂停
          currentContext.pause();
          this.updatePlayIcon(id, false); // 图标切为 play
          this.currentPlayId = null;
          this.currentVideoContext = null;
        } else {
          // 情况2：当前视频未播放 → 播放（先暂停其他视频）
          this.pausePrevVideo(id); // 复用之前的辅助方法
          this.updatePlayIcon(id, true); // 图标切为 pause
          currentContext.play();
          this.currentPlayId = id;
          this.currentVideoContext = currentContext;
        }
      },
      toggleVolume(item) {
        this.hasVolume = !this.hasVolume;
        this.videoMuted = !this.videoMuted;
      },
      stopAll() {
        // #ifdef H5
        this.videoElList.forEach((item) => {
          item.$el.querySelector("video").pause();
        });
        // #endif
      },
      initVideoEl() {
        this.videoElList = [];
        // #ifdef H5
        this.$nextTick(() => {
          this.videoElList = [];
          this.formatVideos.forEach((item) => {
            const videoEl = this.$refs[`video${item.id}`];
            if (!videoEl || !videoEl[0]) return;

            this.videoElList.push(videoEl[0]);
            const videoDom = videoEl[0].$el;
            const videoCoverEl = videoDom.querySelector(".uni-video-cover");
            if (videoCoverEl) videoCoverEl.style.display = "none";
            const videoPlayEl = videoDom.querySelector("video");
            if (!videoPlayEl) return;
            let isProcessing = false;
            // 判断当前videoPlayEl是否已经绑定过事件, 没有hasEventListener方法
            const mouseEnterHandler = async (event) => {
              if (isProcessing) return; // Ignore if already processing
              isProcessing = true;

              try {
                // Pause previous video (use existing logic) instead of stopAll()
                this.pausePrevVideo(item.id);

                // Handle volume
                videoPlayEl.muted = !this.hasVolume;

                // Show pause icon
                this.updatePlayIcon(item.id, true); // 图标切为 pause
                const gridEl = videoEl[0].$el.parentNode;
                // const likeIconEl = gridEl.querySelector(".like-icon-box");
                // if (likeIconEl) likeIconEl.style.color = "#f8f8f8";

                // Play the video (wait for play to resolve)
                await videoPlayEl.play();
                // await videoCoverEl.play().catch((err) => {
                //   console.warn("Play interrupted:", err);
                // });
                this.currentPlayId = item.id; // Update state
              } catch (err) {
                console.warn("Play interrupted:", err);
              } finally {
                isProcessing = false; // Reset flag
              }
            };
            if (!this.mouseenterListeners.has(videoPlayEl)) {
              videoPlayEl.addEventListener("mouseenter", mouseEnterHandler);
            }
            const mouseLeaveHandler = async (event) => {
              if (isProcessing) return;
              isProcessing = true;

              try {
                this.updatePlayIcon(item.id, false); // 图标切为 pause

                // Pause and reset only if this is the current playing video
                if (this.currentPlayId === item.id) {
                  await videoPlayEl.pause();
                  videoPlayEl.currentTime = 0;
                  this.currentPlayId = null; // Reset state
                }
              } catch (err) {
                console.warn("Pause interrupted:", err);
              } finally {
                isProcessing = false;
              }
            };
            if (!this.mouseleaveListeners.has(videoPlayEl)) {
              videoPlayEl.addEventListener("mouseleave", mouseLeaveHandler);
            }
          });
        });
        // #endif
      },
      showPlayIcon(gridEl, isPause = true) {
        const iconEl = gridEl.querySelector(".iconfont");
        if (isPause) {
          iconEl.classList.add("icon-play");
          iconEl.classList.remove("icon-pause");
        } else {
          iconEl.classList.add("icon-pause");
          iconEl.classList.remove("icon-play");
        }
      },
    },
    mounted() {
      // #ifdef H5
      this.formatVideos.forEach((item) => {
        const videoEl = this.$refs[`video${item.id}`];
        this.videoElList.push(videoEl[0]);
        const videoDom = videoEl[0].$el;
        if (videoDom.querySelector) {
          videoDom.querySelector(".uni-video-cover").style.display = "none";
        }
      });
      // #endif
    },
    watch: {
      videoList: {
        handler(newVal) {
          const formatVideos = newVal.map((item) => ({
            ...item,
            playIconClass: "iconfont icon-play",
            iconColor: "#fff",
            hasMuted: true,
            likeColor: "#f00",
          }));
          this.formatVideos = formatVideos;

          this.initVideoEl();
        },
        deep: true,
        immediate: true,
      },
    },
  };
</script>

<style scoped>
  .like-item {
    display: inline-block;
    position: absolute;
    right: 10px;
    margin-right: 0;
    width: 20px;
    height: 20px;
    line-height: 20px;
    padding: 0;
    z-index: 100;
  }
  .video-container {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    margin-bottom: 55px;
  }
  .video-view {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    padding: auto 16px;
    font-size: 14px;
    width: 100%;
  }
  .video-item {
    display: flex;
    height: 120px;
    width: 33.333%;
    justify-content: center;
    align-items: center;
  }
  .el-row {
    width: 100%;
  }
  .el-col {
    padding: 0 5px;
  }
  .grid-content {
    border-radius: 4px;
    min-height: 36px;
    padding-bottom: 10px;
    position: relative;
  }
  .item-video {
    width: 100%;
    height: 200px;
    object-fit: cover;
  }
  .video-desc {
    overflow-x: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .like-box {
    position: absolute;
    bottom: 35px;
    /* left: 5px; */
    padding-left: 5px;
    width: 100%;
    display: flex;
  }
  .like-icon-box {
    width: 22px;
    height: 22px;
    margin-right: 10px;
    box-sizing: border-box;
    z-index: 100;
  }
  /* .like-icon-box svg {
    width: 100%;
    height: 100%;
    display: block;
  } */
  .like-count {
    padding-right: 5px;
    color: #ffffff;
  }
  .row-end {
    margin-bottom: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 20px;
    text-align: center;
    width: 100%;
  }
  /* #ifdef MP-WEIXIN */
  .row-content ::v-deep .uni-row,
  .row-end ::v-deep .uni-row {
    width: 100% !important;
    text-align: center;
  }
  .col-end {
    text-align: center;
  }
  /* #endif */
</style>
